<?php

require_once 'BancoDeDados.php';
require_once 'TipoUnidade.php';
require_once 'Objeto.php';

class Unidade {

    private $cod_unidade;
    private $descricao;
    private $tipo_unidade;
    private $valor;
    private $vinculado;
    private $objeto;

    public function &getCod_unidade() {
        return $this->cod_unidade;
    }

    public function setCod_unidade(&$cod_unidade) {
        $this->cod_unidade = &$cod_unidade;
    }

    public function &getDescricao() {
        return $this->descricao;
    }

    public function setDescricao(&$descricao) {
        $this->descricao = &$descricao;
    }

    /**
     *
     * @return TipoUnidade
     */
    public function &getTipo_unidade() {
        return $this->tipo_unidade;
    }

    public function setTipo_unidade(TipoUnidade &$tipo_unidade) {
        $this->tipo_unidade = &$tipo_unidade;
    }

    public function &getValor() {
        return $this->valor;
    }

    public function setValor(&$valor) {
        $this->valor = &$valor;
    }

    public function &isVinculado() {
        return $this->vinculado;
    }

    public function setVinculado(&$vinculado) {
        $this->vinculado = &$vinculado;
    }

    /**
     *
     * @return Objeto
     */
    public function &getObjeto() {
        return $this->objeto;
    }

    public function setObjeto(Objeto &$objeto) {
        $this->objeto = &$objeto;
    }

    public function cadastrar() {
        if ($this->validar() != 1) {
            throw new Exception("Unidade existente");
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('insert into unidade (descricao) values(?)');
        $result = $link->execute($stmt, array($this->descricao));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function alterarCampo(&$campo_id, &$campo_valor) {
        if ($campo_id == 'descricao' && $this->descricao != $campo_valor) {
            $this->descricao = &$campo_valor;
            if ($this->validar() != 1) {
                throw new Exception("Unidade existente");
            }
        } else {
            throw new Exception('no_action');
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('update unidade set ' . $campo_id . ' = ? where cod_unidade = ?');
        $result = $link->execute($stmt, array($campo_valor, $this->cod_unidade));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function excluir() {
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('delete from unidade where cod_unidade = ?');
        $result = $link->execute($stmt, array($this->cod_unidade));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public static function &listar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from unidade');
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = array();
        while ($result->fetchInto($row)) {
            $unidade = new Unidade();
            $unidade->setCod_unidade($row['cod_unidade']);
            $unidade->setDescricao($row['descricao']);
            $unidade->setVinculado($unidade->verificarVinculacao());
            $resultado[] = &$unidade;
            unset($unidade);
        }
        return $resultado;
    }

    public static function &listarPorObjeto(Objeto $objeto) {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_unidade, descricao, cod_tipo_unidade, valor from unidade, objeto_unidade where unidade.cod_unidade = objeto_unidade.cod_unidade and cod_interno = ?', array($objeto->getCod_interno()));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = array();
        while ($result->fetchInto($row)) {
            $unidade = new Unidade();
            $unidade->setCod_unidade($row['cod_unidade']);
            $unidade->setDescricao($row['descricao']);
            $unidade->setValor($row['valor']);
            $unidade->setTipo_unidade(TipoUnidade::consultar($row['cod_tipo_unidade']));
            $unidade->setObjeto($objeto);
            $resultado[] = &$unidade;
            unset($unidade);
        }
        return $resultado;
    }

    /**
     *
     * @param <type> $cod_unidade
     * @return Unidade
     */
    public static function &consultar(&$cod_unidade) {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select * from unidade where cod_unidade = ?', array($cod_unidade));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() == 0) {
            throw new Exception("Unidade inexistente");
        } elseif ($result->numRows() > 1) {
            throw new Exception("Mais de um Unidade com o mesmo identificador, infounidadee ao administrador");
        }
        $result->fetchInto($row);
        $unidade = new Unidade();
        $unidade->setCod_unidade($row['cod_unidade']);
        $unidade->setDescricao($row['descricao']);
        return $unidade;
    }

    private function &validar() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_unidade from unidade where descricao = ?', array($this->descricao));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = 1;
        if ($result->numRows() > 0) {
            $resultado = 0;
        }
        return $resultado;
    }

    private function &verificarVinculacao() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_unidade from objeto_unidade where cod_unidade = ?', array($this->cod_unidade));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        $resultado = 0;
        if ($result->numRows() > 0) {
            $resultado = 1;
        }
        return $resultado;
    }

    public function cadastrarObjeto() {
        $banco = BancoDeDados::getInstance();
        $result = $banco->getLink()->query('select cod_unidade from objeto_unidade where cod_unidade = ? and cod_interno = ?', array($this->cod_unidade, $this->objeto->getCod_interno()));
        if (DB::isError($result)) {
            throw new Exception($result->getMessage());
        }
        if ($result->numRows() > 0) {
            throw new Exception('Aquisição existente');
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('insert into objeto_unidade (cod_interno, cod_unidade, cod_tipo_unidade) values(?,?,?)');
        $result = $link->execute($stmt, array($this->objeto->getCod_interno(), $this->cod_unidade, $this->tipo_unidade->getCod_tipo_unidade()));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function alterarObjeto(&$campo_id, TipoUnidade &$campo_valor) {
        if ($campo_id == 'cod_tipo_unidade' && $this->tipo_unidade->getCod_tipo_unidade() != $campo_valor->getCod_tipo_unidade()) {
            $this->descricao = &$campo_valor;
        } else {
            throw new Exception('no_action');
        }
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('update objeto_unidade set ' . $campo_id . ' = ? where cod_unidade = ? and cod_interno = ?');
        $result = $link->execute($stmt, array($campo_valor->getCod_tipo_unidade(), $this->cod_unidade, $this->objeto->getCod_interno()));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

    public function excluirObjeto() {
        $banco = BancoDeDados::getInstance();
        $link = $banco->getLink();
        $stmt = $link->prepare('delete from objeto_unidade where cod_unidade = ? and cod_interno = ?');
        $result = $link->execute($stmt, array($this->cod_unidade, $this->objeto->getCod_interno()));
        if (DB::isError($result)) {
            $link->rollBack();
            throw new Exception($result->getMessage());
        }
        $link->commit();
    }

}
?>